home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / uucp-104.lha / uucp-1.04 / xcmd.c < prev   
C/C++ Source or Header  |  1993-02-13  |  10KB  |  397 lines

  1. /* xcmd.c
  2.    Routines to handle work requests.
  3.  
  4.    Copyright (C) 1991, 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.9 1993/01/19 05:10:46 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33.  
  34. #include "uudefs.h"
  35. #include "uuconf.h"
  36. #include "system.h"
  37. #include "prot.h"
  38. #include "trans.h"
  39.  
  40. /* Local functions.  */
  41.  
  42. static boolean flocal_xcmd_request P((struct stransfer *qtrans,
  43.                       struct sdaemon *qdaemon));
  44. static boolean flocal_xcmd_await_reply P((struct stransfer *qtrans,
  45.                       struct sdaemon *qdaemon,
  46.                       const char *zdata, size_t cdata));
  47. static boolean fremote_xcmd_reply P((struct stransfer *qtrans,
  48.                      struct sdaemon *qdaemon));
  49.  
  50. /* Handle a local work request.  We just set up the request for
  51.    transmission.  */
  52.  
  53. boolean
  54. flocal_xcmd_init (qdaemon, qcmd)
  55.      struct sdaemon *qdaemon;
  56.      struct scmd *qcmd;
  57. {
  58.   struct stransfer *qtrans;
  59.  
  60.   qtrans = qtransalc (qcmd);
  61.   qtrans->psendfn = flocal_xcmd_request;
  62.  
  63.   return fqueue_local (qdaemon, qtrans);
  64. }
  65.  
  66. /* Send the execution request to the remote system.  */
  67.  
  68. static boolean
  69. flocal_xcmd_request (qtrans, qdaemon)
  70.      struct stransfer *qtrans;
  71.      struct sdaemon *qdaemon;
  72. {
  73.   size_t clen;
  74.   char *zsend;
  75.   boolean fret;
  76.  
  77.   ulog (LOG_NORMAL, "Requesting work: %s to %s", qtrans->s.zfrom,
  78.     qtrans->s.zto);
  79.  
  80.   /* We send the string
  81.      X from to user options
  82.      We put a dash in front of options.  */
  83.   clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto)
  84.       + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 7);
  85.   zsend = zbufalc (clen);
  86.   sprintf (zsend, "X %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto,
  87.        qtrans->s.zuser, qtrans->s.zoptions);
  88.  
  89.   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
  90.                     qtrans->iremote);
  91.   ubuffree (zsend);
  92.   if (! fret)
  93.     {
  94.       utransfree (qtrans);
  95.       return FALSE;
  96.     }
  97.  
  98.   qtrans->fcmd = TRUE;
  99.   qtrans->precfn = flocal_xcmd_await_reply;
  100.  
  101.   return fqueue_receive (qdaemon, qtrans);
  102. }
  103.  
  104. /* Get a reply to an execution request from the remote system.  */
  105.  
  106. /*ARGSUSED*/
  107. static boolean
  108. flocal_xcmd_await_reply (qtrans, qdaemon, zdata, cdata)
  109.      struct stransfer *qtrans;
  110.      struct sdaemon *qdaemon;
  111.      const char *zdata;
  112.      size_t cdata;
  113. {
  114.   qtrans->precfn = NULL;
  115.  
  116.   if (zdata[0] != 'X'
  117.       || (zdata[1] != 'Y' && zdata[1] != 'N'))
  118.     {
  119.       ulog (LOG_ERROR, "Bad response to work request");
  120.       utransfree (qtrans);
  121.       return FALSE;
  122.     }
  123.  
  124.   if (zdata[1] == 'N')
  125.     {
  126.       ulog (LOG_ERROR, "%s: work request denied", qtrans->s.zfrom);
  127.       (void) fmail_transfer (FALSE, qtrans->s.zuser, (const char *) NULL,
  128.                  "work request denied",
  129.                  qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
  130.                  qtrans->s.zto, (const char *) NULL,
  131.                  (const char *) NULL);
  132.     }
  133.  
  134.   (void) fsysdep_did_work (qtrans->s.pseq);
  135.   utransfree (qtrans);
  136.  
  137.   return TRUE;
  138. }
  139.  
  140. /* Handle a remote work request.  This just queues up the requests for
  141.    later processing.  */
  142.  
  143. boolean
  144. fremote_xcmd_init (qdaemon, qcmd, iremote)
  145.      struct sdaemon *qdaemon;
  146.      struct scmd *qcmd;
  147.      int iremote;
  148. {
  149.   const struct uuconf_system *qsys;
  150.   const char *zexclam;
  151.   const struct uuconf_system *qdestsys;
  152.   struct uuconf_system sdestsys;
  153.   char *zdestfile;
  154.   boolean fmkdirs;
  155.   struct stransfer *qtrans;
  156.   char *zuser;
  157.   char aboptions[5];
  158.   char *zfrom;
  159.   boolean fret;
  160.   char *zfile;
  161.  
  162.   ulog (LOG_NORMAL, "Work requested: %s to %s", qcmd->zfrom,
  163.     qcmd->zto);
  164.  
  165.   qsys = qdaemon->qsys;
  166.  
  167.   zexclam = strchr (qcmd->zto, '!');
  168.   if (zexclam == NULL
  169.       || zexclam == qcmd->zto
  170.       || strncmp (qdaemon->zlocalname, qcmd->zto,
  171.           (size_t) (zexclam - qcmd->zto)) == 0)
  172.     {
  173.       const char *zconst;
  174.  
  175.       /* The files are supposed to be copied to the local system.  */
  176.       qdestsys = NULL;
  177.       if (zexclam == NULL)
  178.     zconst = qcmd->zto;
  179.       else
  180.     zconst = zexclam + 1;
  181.  
  182.       zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir);
  183.       if (zdestfile == NULL)
  184.     return FALSE;
  185.  
  186.       zuser = NULL;
  187.       fmkdirs = strchr (qcmd->zoptions, 'f') != NULL;
  188.     }
  189.   else
  190.     {
  191.       size_t clen;
  192.       char *zcopy;
  193.       int iuuconf;
  194.       char *zoptions;
  195.  
  196.       clen = zexclam - qcmd->zto;
  197.       zcopy = zbufalc (clen + 1);
  198.       memcpy (zcopy, qcmd->zto, clen);
  199.       zcopy[clen] = '\0';
  200.  
  201.       iuuconf = uuconf_system_info (qdaemon->puuconf, zcopy, &sdestsys);
  202.       if (iuuconf == UUCONF_NOT_FOUND)
  203.     {
  204.       if (! funknown_system (qdaemon->puuconf, zcopy, &sdestsys))
  205.         {
  206.           ulog (LOG_ERROR, "%s: System not found", zcopy);
  207.           ubuffree (zcopy);
  208.           qtrans = qtransalc (qcmd);
  209.           qtrans->psendfn = fremote_xcmd_reply;
  210.           qtrans->pinfo = (pointer) "XN";
  211.           qtrans->iremote = iremote;
  212.           return fqueue_remote (qdaemon, qtrans);
  213.         }
  214.     }
  215.       else if (iuuconf != UUCONF_SUCCESS)
  216.     {
  217.       ulog_uuconf (LOG_ERROR, qdaemon->puuconf, iuuconf);
  218.       ubuffree (zcopy);
  219.       return FALSE;
  220.     }
  221.  
  222.       ubuffree (zcopy);
  223.  
  224.       qdestsys = &sdestsys;
  225.       zdestfile = zbufcpy (zexclam + 1);
  226.  
  227.       zuser = zbufalc (strlen (qdestsys->uuconf_zname)
  228.                + strlen (qcmd->zuser) + sizeof "!");
  229.       sprintf (zuser, "%s!%s", qdestsys->uuconf_zname, qcmd->zuser);
  230.       zoptions = aboptions;
  231.       *zoptions++ = 'C';
  232.       if (strchr (qcmd->zoptions, 'd') != NULL)
  233.     *zoptions++ = 'd';
  234.       if (strchr (qcmd->zoptions, 'm') != NULL)
  235.     *zoptions++ = 'm';
  236.       *zoptions = '\0';
  237.       fmkdirs = TRUE;
  238.     }
  239.  
  240.   /* At this point we prepare to confirm the remote request.  We could
  241.      actually fork here and let the child spool up the requests.  */
  242.   qtrans = qtransalc (qcmd);
  243.   qtrans->psendfn = fremote_xcmd_reply;
  244.   qtrans->pinfo = (pointer) "XY";
  245.   qtrans->iremote = iremote;
  246.   if (! fqueue_remote (qdaemon, qtrans))
  247.     {
  248.       ubuffree (zdestfile);
  249.       ubuffree (zuser);
  250.       return FALSE;
  251.     }
  252.  
  253.   /* Now we have to process each source file.  The source
  254.      specification may or may use wildcards.  */
  255.   zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir);
  256.   if (zfrom == NULL)
  257.     {
  258.       ubuffree (zdestfile);
  259.       ubuffree (zuser);
  260.       return FALSE;
  261.     }
  262.  
  263.   if (! fsysdep_wildcard_start (zfrom))
  264.     {
  265.       ubuffree (zfrom);
  266.       ubuffree (zdestfile);
  267.       ubuffree (zuser);
  268.       return FALSE;
  269.     }
  270.  
  271.   fret = TRUE;
  272.  
  273.   while ((zfile = zsysdep_wildcard (zfrom)) != NULL)
  274.     {
  275.       char *zto;
  276.       char abtname[CFILE_NAME_LEN];
  277.  
  278.       if (! fsysdep_file_exists (zfile))
  279.     {
  280.       ulog (LOG_ERROR, "%s: no such file", zfile);
  281.       continue;
  282.     }
  283.  
  284.       /* Make sure the remote system is permitted to read the
  285.      specified file.  */
  286.       if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send,
  287.                 qsys->uuconf_zpubdir, TRUE, TRUE,
  288.                 (const char *) NULL))
  289.     {
  290.       ulog (LOG_ERROR, "%s: not permitted to send", zfile);
  291.       break;
  292.     }
  293.  
  294.       if (qdestsys != NULL)
  295.     {
  296.       /* We really should get the original grade here.  */
  297.       zto = zsysdep_data_file_name (qdestsys, qdaemon->zlocalname,
  298.                     BDEFAULT_UUCP_GRADE, FALSE,
  299.                     abtname, (char *) NULL,
  300.                     (char *) NULL);
  301.       if (zto == NULL)
  302.         {
  303.           fret = FALSE;
  304.           break;
  305.         }
  306.     }
  307.       else
  308.     {
  309.       zto = zsysdep_add_base (zdestfile, zfile);
  310.       if (zto == NULL)
  311.         {
  312.           fret = FALSE;
  313.           break;
  314.         }
  315.       /* We only accept a local destination if the remote system
  316.          has the right to create files there.  */
  317.       if (! fin_directory_list (zto, qsys->uuconf_pzremote_receive,
  318.                     qsys->uuconf_zpubdir, TRUE, FALSE,
  319.                     (const char *) NULL))
  320.         {
  321.           ulog (LOG_ERROR, "%s: not permitted to receive", zto);
  322.           ubuffree (zto);
  323.           break;
  324.         }
  325.     }
  326.  
  327.       /* Copy the file either to the final destination or to the
  328.      spool directory.  */
  329.       if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs))
  330.     {
  331.       ubuffree (zto);
  332.       break;
  333.     }
  334.  
  335.       ubuffree (zto);
  336.  
  337.       /* If there is a destination system, queue it up.  */
  338.       if (qdestsys != NULL)
  339.     {
  340.       struct scmd ssend;
  341.       char *zjobid;
  342.  
  343.       ssend.bcmd = 'S';
  344.       ssend.pseq = NULL;
  345.       ssend.zfrom = zfile;
  346.       ssend.zto = zdestfile;
  347.       ssend.zuser = zuser;
  348.       ssend.zoptions = aboptions;
  349.       ssend.ztemp = abtname;
  350.       ssend.imode = ixsysdep_file_mode (zfile);
  351.       ssend.znotify = "";
  352.       ssend.cbytes = -1;
  353.       ssend.zcmd = NULL;
  354.       ssend.ipos = 0;
  355.  
  356.       zjobid = zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE,
  357.                        1, &ssend);
  358.       if (zjobid == NULL)
  359.         break;
  360.       ubuffree (zjobid);
  361.     }
  362.  
  363.       ubuffree (zfile);
  364.     }
  365.  
  366.   if (zfile != NULL)
  367.     ubuffree (zfile);
  368.  
  369.   (void) fsysdep_wildcard_end ();
  370.  
  371.   ubuffree (zdestfile);
  372.   if (qdestsys != NULL)
  373.     (void) uuconf_system_free (qdaemon->puuconf, &sdestsys);
  374.  
  375.   ubuffree (zfrom);
  376.   ubuffree (zuser);
  377.  
  378.   return fret;
  379. }
  380.  
  381. /* Reply to a remote work request.  */
  382.  
  383. static boolean
  384. fremote_xcmd_reply (qtrans, qdaemon)
  385.      struct stransfer *qtrans;
  386.      struct sdaemon *qdaemon;
  387. {
  388.   boolean fret;
  389.  
  390.   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon,
  391.                     (const char *) qtrans->pinfo,
  392.                     qtrans->ilocal,
  393.                     qtrans->iremote);
  394.   utransfree (qtrans);
  395.   return fret;
  396. }
  397.